package cn.iocoder.yudao.framework.handlermapping;

import cn.iocoder.yudao.framework.message.ClientRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * @author 王广帅
 * @date 2021年01月26日 4:35 下午
 */
public class NettyWsHandlerMappingManager {

    private static NettyWsHandlerMappingManager instance = new NettyWsHandlerMappingManager();


    private Logger logger = LoggerFactory.getLogger(NettyWsHandlerMappingManager.class);

    private Map<String, NettyWsMappingMethod> gameMappingMethodMap = new HashMap<>();

    private NettyWsHandlerMappingManager() {
    }

    public static NettyWsHandlerMappingManager getInstance() {
        return instance;
    }

    /**
     * 从Sring的容器中读取GameHandlerComponent标记的实例
     *
     * @param context
     */
    public void scanGameHandler(ApplicationContext context) {
        String[] handlerBeanNames = context.getBeanNamesForAnnotation(NettyWsHandlerComponent.class);
        logger.debug("----->加载GameHandlerComponent的bean数量:{}", handlerBeanNames.length);
        for (String beanName : handlerBeanNames) {
            Object beanObj = context.getBean(beanName);
            //查找处理请求的方法
            Method[] methods = beanObj.getClass().getMethods();
            for (Method method : methods) {
                NettyWsMapping nettyWsMapping = method.getAnnotation(NettyWsMapping.class);
                if (nettyWsMapping != null) {
                    String uri = nettyWsMapping.value();
                    NettyWsMappingMethod nettyWsMappingMethod = new NettyWsMappingMethod(beanObj, method);
                    gameMappingMethodMap.put(uri, nettyWsMappingMethod);
                }
            }
        }
    }

    public void callMethod(NettyWsChannelContext ctx, ClientRequest request)
            throws Exception {
        NettyWsMappingMethod nettyWsMappingMethod = gameMappingMethodMap.get(request.getUri());
        if (nettyWsMappingMethod == null) {
            throw new IllegalArgumentException("不存在此消息的处理方法,uri:" + request.getUri());
        }
        Method handlerMethod = nettyWsMappingMethod.getHandlerMethod();
        handlerMethod.invoke(nettyWsMappingMethod.getHandlerObj(), ctx, request);
    }
}
